home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Applications / Macintosh Tracker 1.20 / source / Server⁄Tracker 4.0 / open.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-02-01  |  5.8 KB  |  310 lines  |  [TEXT/KAHL]

  1. /* open.c */
  2.  
  3. /* Magic open file: path lookup and transparent decompression */
  4.  
  5. /* $Id: open.c,v 4.1 1994/01/12 16:11:07 espie Exp espie $ 
  6.  * $Log: open.c,v $
  7.  * Revision 4.1  1994/01/12  16:11:07  espie
  8.  * Last minute changes.
  9.  *
  10.  * Revision 4.0  1994/01/11  17:50:46  espie
  11.  * A little more abstract, should work better
  12.  *
  13.  * Revision 1.6  1994/01/09  17:36:22  Espie
  14.  * Generalized open.c.
  15.  *
  16.  * Revision 1.5  1994/01/08  19:43:57  Espie
  17.  * Better amiga patterns.
  18.  *
  19.  * Revision 1.4  1994/01/05  16:10:49  Espie
  20.  * *** empty log message ***
  21.  *
  22.  * Revision 1.3  1994/01/05  14:54:09  Espie
  23.  * *** empty log message ***
  24.  *
  25.  * Revision 1.2  1994/01/05  13:50:43  Espie
  26.  * Cosmetic change.
  27.  *
  28.  * Revision 1.1  1993/12/26  00:55:53  Espie
  29.  * Initial revision
  30.  *
  31.  * Revision 3.12  1993/12/04  16:12:50  espie
  32.  * New semantics.
  33.  *
  34.  * Revision 3.11  1993/12/02  15:45:33  espie
  35.  * Simpler.
  36.  *
  37.  * Revision 3.10  1993/11/27  17:29:53  espie
  38.  * Suppressed stupid abstraction.
  39.  *
  40.  * Revision 3.9  1993/11/17  15:31:16  espie
  41.  * *** empty log message ***
  42.  *
  43.  * Revision 3.8  1993/11/11  20:00:03  espie
  44.  * Amiga support.
  45.  *
  46.  * Revision 3.7  1993/08/17  16:53:09  espie
  47.  * New gzip suffix.
  48.  *
  49.  * Revision 3.3  1993/07/14  16:33:41  espie
  50.  * Added gzip/shorten.
  51.  *
  52.  * Revision 3.2  1992/12/03  15:00:50  espie
  53.  * restore stty.
  54.  *
  55.  * Revision 3.1  1992/11/19  20:44:47  espie
  56.  * Protracker commands.
  57.  *
  58.  * Revision 3.0  1992/11/18  16:08:05  espie
  59.  * New release.
  60.  *
  61.  * Revision 1.5  1992/11/01  13:10:06  espie
  62.  * Cleaned up path handler, and some more bugs.
  63.  * Check for size now.
  64.  * Added path support. Transparent interface. We look up through the file
  65.  * list, which is small anyway.
  66.  */
  67.  
  68. #include "defs.h"
  69.  
  70. #include <stdio.h>
  71. #include <string.h>
  72. #include <ctype.h>
  73. #ifdef MALLOC_NOT_IN_STDLIB
  74. #include <malloc.h>
  75. #else
  76. #include <stdlib.h>
  77. #endif
  78.  
  79. #include "extern.h"
  80.  
  81. ID("$Id: open.c,v 4.1 1994/01/12 16:11:07 espie Exp espie $")
  82.  
  83. extern int error;
  84.  
  85. struct exfile
  86.    {
  87.    FILE *handle;
  88.    void (*close)P((struct exfile *f));
  89.    void (*rewind)P((struct exfile *f));
  90.    int (*getcar)P((struct exfile *f));
  91.    int (*tell)P((struct exfile *f));
  92.    int pos;
  93.    };
  94.  
  95. LOCAL int do_getchar(f)
  96. struct exfile *f;
  97.    {
  98.    int c;
  99.  
  100.    if ((c = fgetc(f->handle)) == EOF)
  101.       error = FILE_TOO_SHORT;
  102.    else
  103.       f->pos++;
  104.    return c;
  105.    }
  106.  
  107. LOCAL int do_tell(f)
  108. struct exfile *f;
  109.    {
  110.    return f->pos;
  111.    }
  112.  
  113. LOCAL void do_pclose(f)
  114. struct exfile *f;
  115.    {
  116.    pclose(f->handle);
  117.    }
  118.  
  119. LOCAL void do_fclose(f)
  120. struct exfile *f;
  121.    {
  122.    fclose(f->handle);
  123.    }
  124.  
  125.    
  126. /* compression methods we do know about.
  127.  * Important restriction: for the time being, the output
  128.  * must be a single module.
  129.  */
  130.  
  131. LOCAL struct compression_method
  132.    {
  133.    char *extension;
  134.    char *command;
  135.    } comp_table[] =
  136.    {
  137.    ".czip", "unczip %s",
  138.    ".gz",   "gzip -dc %s",
  139. #ifdef GZIP
  140.    ".z", "gzip -dc %s",
  141. #else
  142.     ".Z",   "zcat %s",
  143. #endif
  144.    ".s", "shorten -x %s -",
  145.    ".shn",  "shorten -x %s -",
  146.    ".zoo", "zoo xpq %s",
  147. #ifdef AMIGA
  148.    ".lzh", "lha -q p \"%s\"",
  149.    ".lha", "lha -q p \"%s\"",
  150. #else
  151.    ".lzh", "lha pq %s",
  152.    ".lha", "lha pq %s",
  153. #endif
  154.    ".zip", "unzip -pq %s",
  155.    ".arc", "arc pn %s",
  156.    NULL,   NULL
  157.    };
  158.  
  159. /***
  160.  *
  161.  *  Handling extensions.
  162.  *
  163.  ***/
  164.  
  165. LOCAL boolean check_ext(s, ext)
  166. char *s, *ext;
  167.    {
  168.    int ext_len, s_len;
  169.    char *c;
  170.  
  171.    ext_len = strlen(ext);
  172.    s_len = strlen(s);
  173.    if (s_len < ext_len)
  174.       return FALSE;
  175.    for (c = s + s_len - ext_len; *c; c++, ext++)
  176.       if (tolower(*c) != tolower(*ext))
  177.          return FALSE;
  178.    return TRUE;
  179.    }
  180.  
  181. LOCAL boolean exist_file(fname)
  182. char *fname;
  183.    {
  184.    FILE *temp;
  185.  
  186.    temp = fopen(fname, "r");
  187.    if (temp)
  188.       {
  189.       fclose(temp);
  190.       return TRUE;
  191.       }
  192.    else
  193.       return FALSE;
  194.    }
  195.  
  196. #ifndef MAXPATHLEN
  197. #define MAXPATHLEN 350
  198. #endif
  199.  
  200. LOCAL char *find_file(fname, path)
  201. char *fname;
  202. char *path;
  203.    {
  204.    char *sep;
  205.    static char buffer[MAXPATHLEN];
  206.    int len;
  207.  
  208.       /* first, check the current directory */
  209.    if (exist_file(fname))
  210.       return fname;
  211.    while(path)
  212.       {
  213.       sep = strchr(path, ':');
  214.       if (sep)
  215.          len = sep - path;
  216.       else
  217.          len = strlen(path);
  218.       if (len < MAXPATHLEN)
  219.          {
  220.          strncpy(buffer, path, len);
  221.          buffer[len] = '/';
  222.          if (len + strlen(fname) < MAXPATHLEN - 5)
  223.             {
  224.             strcpy(buffer + len + 1, fname);
  225.             puts(buffer);
  226.             if (exist_file(buffer))
  227.                return buffer;
  228.             }
  229.          }
  230.       if (sep)
  231.          path = sep + 1;
  232.       else
  233.          return NULL;
  234.       }
  235.    return NULL;
  236.    }
  237.  
  238. FILE *file_handle(f)
  239. struct exfile *f;
  240.    {
  241.    return f->handle;
  242.    }
  243.  
  244. int getc_file(f)
  245. struct exfile *f;
  246.    {
  247.    return (*f->getcar)(f);
  248.    }
  249.  
  250. int tell_file(f)
  251. struct exfile *f;
  252.    {
  253.    return (*f->tell)(f);
  254.    }
  255.  
  256. struct exfile *open_file(fname, mode, path)
  257. char *fname;
  258. char *mode; /* right now, only mode "r" is supported */
  259. char *path; 
  260.    {
  261.    struct exfile *new;
  262.    struct compression_method *comp;
  263.  
  264.    if (mode[0] != 'r' || mode[1] != 0)
  265.       return NULL;
  266.     
  267.    new = (struct exfile *)malloc(sizeof(struct exfile));
  268.    if (!new)
  269.       return NULL;
  270.  
  271.    new->getcar = do_getchar;
  272.    new->tell = do_tell;
  273.    new->pos = 0;
  274.    fname = find_file(fname, path);
  275.    if (!fname)
  276.       return NULL;
  277.    for (comp = comp_table; comp->extension; comp++)
  278.       if (check_ext(fname, comp->extension))
  279.          {
  280.          char pipe[MAXPATHLEN + 25];
  281.  
  282.          sprintf(pipe, comp->command, fname);
  283.          new->close = do_pclose;
  284.          if (new->handle = popen(pipe, "r"))
  285.             return new;
  286.          else
  287.             {
  288.             free(new);
  289.             return NULL;
  290.             }
  291.          }
  292.    new->close = do_fclose;
  293.    if (new->handle = fopen(fname, "r"))
  294.       return new;
  295.    else
  296.       {
  297.       free(new);
  298.       return NULL;
  299.       }
  300.    }
  301.  
  302.  
  303. void close_file(file)
  304. struct exfile *file;
  305.    {
  306.    (*file->close)(file);
  307.    free(file);
  308.    }
  309.  
  310.